﻿Imports System
Imports System.CodeDom
Imports System.Globalization
Imports System.Text
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.Activities.Rules
    Friend Class AssignmentStatement
        Inherits RuleCodeDomStatement
        ' Methods
        Private Sub New(ByVal assignStatement As CodeAssignStatement)
            Me.assignStatement = assignStatement
        End Sub

        Friend Overrides Sub AnalyzeUsage(ByVal analysis As RuleAnalysis)
            RuleExpressionWalker.AnalyzeUsage(analysis, Me.assignStatement.Left, False, True, Nothing)
            RuleExpressionWalker.AnalyzeUsage(analysis, Me.assignStatement.Right, True, False, Nothing)
        End Sub

        Friend Overrides Function Clone() As CodeStatement
            Return New CodeAssignStatement { _
                .Left = RuleExpressionWalker.Clone(Me.assignStatement.Left), _
                .Right = RuleExpressionWalker.Clone(Me.assignStatement.Right) _
            }
        End Function

        Friend Shared Function Create(ByVal statement As CodeStatement) As RuleCodeDomStatement
            Return New AssignmentStatement(DirectCast(statement, CodeAssignStatement))
        End Function

        Friend Overrides Sub Decompile(ByVal decompilation As StringBuilder)
            If (Me.assignStatement.Right Is Nothing) Then
                Dim exception As New RuleEvaluationException(Messages.AssignRightNull)
                exception.Data.Item("ErrorObject") = Me.assignStatement
                Throw exception
            End If
            If (Me.assignStatement.Left Is Nothing) Then
                Dim exception2 As New RuleEvaluationException(Messages.AssignLeftNull)
                exception2.Data.Item("ErrorObject") = Me.assignStatement
                Throw exception2
            End If
            RuleExpressionWalker.Decompile(decompilation, Me.assignStatement.Left, Nothing)
            decompilation.Append(" = ")
            RuleExpressionWalker.Decompile(decompilation, Me.assignStatement.Right, Nothing)
        End Sub

        Friend Overrides Sub Execute(ByVal execution As RuleExecution)
            Dim expressionType As Type = execution.Validation.ExpressionInfo(Me.assignStatement.Left).ExpressionType
            Dim operandType As Type = execution.Validation.ExpressionInfo(Me.assignStatement.Right).ExpressionType
            Dim result As RuleExpressionResult = RuleExpressionWalker.Evaluate(execution, Me.assignStatement.Left)
            Dim result2 As RuleExpressionResult = RuleExpressionWalker.Evaluate(execution, Me.assignStatement.Right)
            result.Value = Executor.AdjustType(operandType, result2.Value, expressionType)
        End Sub

        Friend Overrides Function Match(ByVal comperand As CodeStatement) As Boolean
            Dim statement As CodeAssignStatement = [TryCast](comperand,CodeAssignStatement)
            Return (((Not statement Is Nothing) AndAlso RuleExpressionWalker.Match(Me.assignStatement.Left, statement.Left)) AndAlso RuleExpressionWalker.Match(Me.assignStatement.Right, statement.Right))
        End Function

        Friend Overrides Function Validate(ByVal validation As RuleValidation) As Boolean
            Dim flag As Boolean = False
            Dim info As RuleExpressionInfo = Nothing
            If (Me.assignStatement.Left Is Nothing) Then
                Dim item As New ValidationError(Messages.NullAssignLeft, &H541)
                item.UserData.Item("ErrorObject") = Me.assignStatement
                validation.Errors.Add(item)
            Else
                info = validation.ExpressionInfo(Me.assignStatement.Left)
                If (info Is Nothing) Then
                    info = RuleExpressionWalker.Validate(validation, Me.assignStatement.Left, True)
                End If
            End If
            Dim info2 As RuleExpressionInfo = Nothing
            If (Me.assignStatement.Right Is Nothing) Then
                Dim error2 As New ValidationError(Messages.NullAssignRight, &H543)
                error2.UserData.Item("ErrorObject") = Me.assignStatement
                validation.Errors.Add(error2)
            Else
                info2 = RuleExpressionWalker.Validate(validation, Me.assignStatement.Right, False)
            End If
            If ((info Is Nothing) OrElse (info2 Is Nothing)) Then
                Return flag
            End If
            Dim expressionType As Type = info2.ExpressionType
            Dim lhsType As Type = info.ExpressionType
            If (lhsType Is GetType(NullLiteral)) Then
                Dim error3 As New ValidationError(Messages.NullAssignLeft, &H542)
                error3.UserData.Item("ErrorObject") = Me.assignStatement
                validation.Errors.Add(error3)
                Return False
            End If
            If (Not lhsType Is expressionType) Then
                Dim error As ValidationError = Nothing
                If Not RuleValidation.TypesAreAssignable(expressionType, lhsType, Me.assignStatement.Right, [error]) Then
                    If ([error] Is Nothing) Then
                        [error] = New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.AssignNotAllowed, New Object() { RuleDecompiler.DecompileType(expressionType), RuleDecompiler.DecompileType(lhsType) }), &H545)
                    End If
                    [error].UserData.Item("ErrorObject") = Me.assignStatement
                    validation.Errors.Add([error])
                    Return flag
                End If
            End If
            Return True
        End Function


        ' Fields
        Private assignStatement As CodeAssignStatement
    End Class
End Namespace

